package com.xxx.yuedong.community.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.xxx.yuedong.common.R;
import com.xxx.yuedong.common.consts.ActionConstants;
import com.xxx.yuedong.community.controller.form.*;
import com.xxx.yuedong.community.pojo.Dynamic;
import com.xxx.yuedong.community.pojo.DynamicLike;
import com.xxx.yuedong.community.pojo.LikeUser;
import com.xxx.yuedong.common.pojo.PageData;
import com.xxx.yuedong.community.service.DynamicLikeService;
import com.xxx.yuedong.community.service.DynamicService;
import com.xxx.yuedong.utils.EventMsgSendUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Range;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Slf4j
@RestController
@Api(tags = "动态")
@RequestMapping("/dynamic")
public class DynamicController {

    @Autowired
    private DynamicService dynamicService;

    @PostMapping("/insert")
    @ApiOperation("发布动态")
    @SaCheckLogin
    public R insert(@Valid @RequestBody InsertDynamicForm form){
        log.debug("开始处理 【发布动态】 参数{}",form.toString());

        Dynamic dynamic = JSONUtil.parse(form).toBean(Dynamic.class);
        dynamic.setUserId(StpUtil.getLoginIdAsLong());
        dynamic.setCommentCount(0l);
        dynamic.setLikeCount(0l);
        dynamic.setCreateTime(LocalDateTime.now());
        dynamic.setModifyTime(LocalDateTime.now());

//        HashMap param = JSONUtil.parse(form).toBean(HashMap.class);
//        param.put("userId",StpUtil.getLoginIdAsLong());
//        param.put("createTime",LocalDateTime.now());
//        param.put("modifyTime",LocalDateTime.now());
//        param.put("likeCount",0l);
//        param.put("commentCount",0l);


        int rows = dynamicService.insert(dynamic);

        //向被关注的人发送消息
        EventMsgSendUtil.sendEventMsg(StpUtil.getLoginIdAsLong(), dynamic.getId(), ActionConstants.UPDATED);

        return R.ok().put("rows",rows);
    }

    @PostMapping("/update")
    @ApiOperation("编辑动态")
    @SaCheckLogin
    public R update(@Valid @RequestBody UpdateDynamicForm form){
        log.debug("开始处理 【编辑动态】参数{}",form.toString());

        Dynamic dynamic = JSONUtil.parse(form).toBean(Dynamic.class);
        dynamic.setModifyTime(LocalDateTime.now());
        dynamic.setUserId(StpUtil.getLoginIdAsLong());
        int rows = dynamicService.update(dynamic);
        return R.ok().put("rows",rows);
    }


    @PostMapping("/deleteDynamicById")
    @ApiOperation("删除动态")
    @SaCheckLogin
    public R deleteDynamicById(@Valid @RequestBody DeleteDynamicByIdForm form){
        HashMap param = JSONUtil.parse(form).toBean(HashMap.class);
        param.put("userId",StpUtil.getLoginIdAsLong());
        int rows = dynamicService.deleteDynamicById(param);
        return R.ok().put("rows",rows);
    }

    @PostMapping("/searchDynamicDetailById")
    @ApiOperation("动态详情")
    @SaCheckLogin
    public R searchDynamicDetailById(@Valid @RequestBody SearchDynamicDetailByIdForm form){
        HashMap map = dynamicService.searchDynamicDetailById(form.getId());
        return R.ok(map);
    }

    @Autowired
    private DynamicLikeService dynamicLikeService;

    /**
     * 点赞功能
     * 业务架构：
     *  使用Reddis作为缓存，针对高并发情况下热门新闻在2s之内的点赞量可能会达到100+
     *  - 项目启动是Redis进行缓存预热，也就是先同步MySQL再清理之前剩下的Redis中的内容
     *  - 用户点赞之后数据直接存储到Redis中
     *  - Java程序设置定时任务2s从Redis中同步数据到MySQL进行批量插入操做并且清理本次Redis中的缓存
     */
    @PostMapping("/get-like/{dynamicId:[0-9]+}")
    @ApiOperation("点赞动态")
    @ApiOperationSupport(order = 100)
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "dynamicId", value = "动态id", required = true, dataType = "long")
    })
    public R getLike(@PathVariable @NotNull @Range(min = 1,message = "请提交正确的动态id") Long dynamicId){
//        获取点赞者id
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        DynamicLikeForm dynamicLikeForm = new DynamicLikeForm();
        dynamicLikeForm.setUserId(id);
        dynamicLikeForm.setDynamicId(dynamicId);
        dynamicLikeService.getDynamicLike(dynamicLikeForm);
        //发送消息
        EventMsgSendUtil.sendEventMsg(id, dynamicId, ActionConstants.LIKED);
        return R.ok();
    }
    /**
     * 取消点赞功能
     * 使用Reddis作为缓存，针对高并发情况下在2s之内的取消点赞量可能会达到100+
     */
    @PostMapping("/out-like/{dynamicId:[0-9]+}")
    @ApiOperation("取消点赞动态")
    @ApiOperationSupport(order = 200)
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "dynamicId", value = "动态id", required = true, dataType = "long")
    })
    public R outLike(@PathVariable @NotNull @Range(min = 1,message = "请提交正确的动态id") Long dynamicId){
//        获取点赞者id
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        DynamicLikeForm dynamicLikeForm = new DynamicLikeForm();
        dynamicLikeForm.setUserId(id);
        dynamicLikeForm.setDynamicId(dynamicId);
        dynamicLikeService.outDynamicLike(dynamicLikeForm);
        return R.ok();
    }
    /**
     * 获取动态的点赞数量
     * 业务架构：web层(controller)->业务层(service)->dao层(MySQL)
     */
    @GetMapping  ("/count-like/{dynamicId:[0-9]+}")
    @ApiOperationSupport(order = 400)
    @ApiOperation("获取动态的点赞数量")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "dynamicId", value = "动态id", required = true, dataType = "long")
    })
    public R countLike(@PathVariable @NotNull @Range(min = 1,message = "请提交正确的动态id") Long dynamicId){
        int num = dynamicLikeService.countDynamicLike(dynamicId);
        return R.ok().put("num",num);
    }
    /**
     * 获取动态的前四位点赞者
     * 业务架构：web层(controller)->业务层(service)->dao层(MySQL)
     */
    @GetMapping  ("/get-likers/{dynamicId:[0-9]+}")
    @ApiOperationSupport(order = 410)
    @ApiOperation("获取动态的前四位点赞者")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "dynamicId", value = "动态id", required = true, dataType = "long")
    })
    public R getLikers(@PathVariable @NotNull @Range(min = 1,message = "请提交正确的动态id") Long dynamicId){

        List<LikeUser> likeUsers = new ArrayList<>(dynamicLikeService.getDynamicLiker(dynamicId));
        return R.ok().put("likeUsers",likeUsers);
    }

    /**
     * 判断此用户是否点赞过该动态
     * 业务架构：web层(controller)->业务层(service)->dao层(MySQL)
     */
    @GetMapping("/is-liker/{dynamicId:[0-9]+}")
    @ApiOperationSupport(order = 420)
    @ApiOperation("判断当前用户是否点赞过当前动态")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "dynamicId", value = "动态id", required = true, dataType = "long")
    })
    public R isDynamicLiker(@PathVariable @NotNull @Range(min = 1,message = "请提交正确的动态id")Long dynamicId){
//        获取当前用户的id
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        DynamicLike dynamicLike = dynamicLikeService.isDynamicLiker(dynamicId,id);
        if(dynamicLike == null){
            return R.ok().put("isLike","false");
        }
        return R.ok().put("isLike","true");
    }

    /**
     * 获取用户的喜欢列表
     * 业务架构：web层(controller)->业务层(service)->dao层(MySQL)
     */
    @GetMapping("/like-Dynamics/")
    @ApiOperationSupport(order = 430)
    @ApiOperation("获取用户的喜欢列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", defaultValue = "1", paramType = "query", dataType = "long")
    })
    public R dynamicLikes(@Range(min = 1, message = "请提交有效的页码值！") Integer page){
        Integer pageNum = page == null ? 1 : page;
//        获取当前用户id
        Long id = Long.parseLong((String) StpUtil.getLoginId());
//        判断在Redis缓存中是否存在用户的喜欢列表，如果不存在就加载存在则继续下一步
        if(!dynamicLikeService.isDynamicLikeList(id)){
//            加载该用户的喜欢列表
            dynamicLikeService.buildDynamicLikeList(id);
        }
        PageData<Dynamic> pageData = dynamicLikeService.list(pageNum,id);
        return R.ok().put("list",pageData);
    }

    @PostMapping("/searchDynamicByPage")
    @ApiOperation("分页查询所有动态")
    public R searchDynamicByPage(@Valid @RequestBody SearchDynamicByPageForm form){
        log.debug("开始处理 【分页查询所有动态】参数{}",form.toString());
        HashMap param = JSONUtil.parse(form).toBean(HashMap.class);
        R r = dynamicService.searchDynamicByPage(param);
        return r;
    }
}
